#include "handler.h"
#include "session.h"
#include <utility>
#include "server.h"

// bind function.
#define bindFunc(memberFunc) std::bind(&memberFunc, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)

IMPLEMENT_SINGLETON(CClientHandler);
void CClientHandler::Init() {
	m_handlers[0] = bindFunc(CClientHandler::handlePing);
}

bool CClientHandler::HandleMsg(CCliSession* pCliSession, const char* msg, int len) {
	const char* protoMsg = msg + anet::tcp::gProto_head_size;
	unsigned short msgId = ntohs(*(unsigned short*)protoMsg);
	const char* proto = protoMsg + anet::tcp::gProto_message_id_size;

	// set beat heart time.
	pCliSession->SetBeatHeartTime(GetNowMSTime());

	auto it = m_handlers.find(msgId);
	if (it != m_handlers.end()) {
		auto protoLen = len - anet::tcp::gProto_head_size - anet::tcp::gProto_message_id_size;
		if (protoLen < 0) {
			LogACrit("find %d message id, len error:%d", msgId, len);
			return false;
		} else {
			it->second(pCliSession, proto, protoLen);
			return true;
		}
	} else {
		if (auto pGameServer = CServerMgr::Instance()->findGameServer(); pGameServer != nullptr) {
			return pGameServer->remote_call("CGateServer::clientHandler", pCliSession->GetId(), std::string(msg, len));
		} else {
			LogACrit("can not find a game server");
			return false;
		}
	}
}

void CClientHandler::handlePing(CCliSession* pCliSession, const char* proto, int len) {
	const char* gPong = "pong";
	static const unsigned int gSize = strlen(gPong);
	const unsigned short gMsgId = 0;
	pCliSession->Send(gMsgId, gPong, gSize);
}
